package com.dev.op.exceptions;

import com.dev.op.VO.ResultVO;
import com.dev.op.enums.ResultCode;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.MethodArgumentNotValidException;

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    // 自定义业务异常
    @ExceptionHandler(BizException.class)
    public ResultVO<?> handleBizException(BizException ex) {
        log.warn("业务异常：{}", ex.getMessage());
        return ResultVO.error(ex.getCode(), ex.getMessage());
    }

    // 参数校验异常（如 @Valid）
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResultVO<?> handleValidationException(MethodArgumentNotValidException ex) {
        String msg = ex.getBindingResult().getFieldError().getDefaultMessage();
        log.warn("参数校验异常：{}", msg);
        return ResultVO.error(ResultCode.PARAM_ERROR.code(), msg);
    }

    // 权限不足（Spring Security 抛出的 AccessDeniedException）
    @ExceptionHandler(AccessDeniedException.class)
    public ResultVO<?> handleAccessDeniedException(AccessDeniedException ex, HttpServletRequest request) {
        log.warn("权限不足访问 [{}]：{}", request.getRequestURI(), ex.getMessage());
        return ResultVO.error(ResultCode.FORBIDDEN.code(), "权限不足，禁止访问");
    }

    // 未登录或认证失败（如 JWT 过期、无效）
    @ExceptionHandler(AuthenticationException.class)
    public ResultVO<?> handleAuthenticationException(AuthenticationException ex, HttpServletRequest request) {
        log.warn("未认证访问 [{}]：{}", request.getRequestURI(), ex.getMessage());
        return ResultVO.error(ResultCode.UNAUTHORIZED.code(), "未登录或身份已失效");
    }

    // 未知异常兜底
    @ExceptionHandler(Exception.class)
    public ResultVO<?> handleGlobalException(Exception ex) {
        log.error("系统异常：", ex);
        return ResultVO.error(ResultCode.SYSTEM_ERROR.code(), "系统异常：" + ex.getMessage());
    }
}

